package com.ifast.common.utils.alioss;

import cn.hutool.core.io.FileUtil;
import com.google.common.collect.Maps;
import com.xiaoleilu.hutool.date.DateUtil;
import org.springframework.web.multipart.MaxUploadSizeExceededException;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.multipart.MultipartHttpServletRequest;
import org.springframework.web.multipart.commons.CommonsMultipartResolver;

import javax.servlet.http.HttpServletRequest;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.text.SimpleDateFormat;
import java.util.*;


/**
 * 
 *@Description:文件上传（使用SpringMVC提供的上传文件）
 *@Author:afast
 *@Since:2016-4-22上午09:34:13
 */
public class UploadUtils{
   
    private static final Map<String, String> EXT_MAP;
    
    static{
        EXT_MAP = new HashMap<String, String>();
        EXT_MAP.put("image", "gif,jpg,jpeg,png,bmp");
        EXT_MAP.put("flash", "swf,flv");
        EXT_MAP.put("media", "swf,flv,mp3,wav,wma,wmv,mid,avi,mpg,asf,rm,rmvb,mp4");
        EXT_MAP.put("file", "doc,docx,xls,xlsx,ppt,htm,html,txt,zip,rar,gz,bz2,apk");
    }
    
    // 文件保存根目录
    private static final String ROOt_BASE_PATH = "/upload";
    
 // 文件保存根目录
    private static final String ROOT_BASE_PATH_ALI = "upload";
    
    
    //创建文件保存文件夹
    private static void createFileDir(String savePath){
        File uploadDir = new File(savePath);
        if(!uploadDir.exists()){
            uploadDir.mkdirs();
        }
    }
    
    private static UploadResult upload(HttpServletRequest request, String fileType, String basePath, Integer maxSize){
    	// 文件保存目录url
    	String saveUrl  = createSaveURL(basePath);
    	//文件保存物理路径
    	String savePath = request.getSession().getServletContext().getRealPath("") + saveUrl;
    	//创建文件保存文件夹
    	createFileDir(savePath);
    	
    	UploadResult result = new UploadResult();
    	
        //解析器解析request的上下文
        CommonsMultipartResolver multipartResolver = new CommonsMultipartResolver(request.getSession().getServletContext());
        //先判断request中是否包涵multipart类型的数据，
        if(multipartResolver.isMultipart(request)){
            //再将request中的数据转化成multipart类型的数据
            MultipartHttpServletRequest multiRequest = (MultipartHttpServletRequest)request;
            Iterator<String> iter = multiRequest.getFileNames();
            while(iter.hasNext()){
                MultipartFile file = multiRequest.getFile(iter.next());
                if(file != null){
                    String fileName = file.getOriginalFilename();
                    if(!fileName.trim().equals("")){
                        try {
                        	if(maxSize!=null && file.getSize()>maxSize*1024){
                        		throw new MaxUploadSizeExceededException(maxSize*1024);
                        	}
                        	fileName = recreateFileName(getFileExt(fileName, fileType));
                            File localFile = new File(savePath,fileName);
                        	file.transferTo(localFile);
                        } catch (IOException e) {
                            result.setMessage("文件上传失败");
                            result.setSuccess(false);
                            result.getFileURLs().clear();
                            break;
                        } catch (MaxUploadSizeExceededException e){
                        	result.setMessage("上传文件大小超过限制");
                        	result.setSuccess(false);
                        	result.getFileURLs().clear();
                        	break;
                        } catch (Exception e){
                        	result.setMessage("上传文件扩展名是不允许的扩展名。\n只允许" + EXT_MAP.get(fileType) + "格式");
                        	result.setSuccess(false);
                        	result.getFileURLs().clear();
                        	break;
                        }
                        result.getFileURLs().add(saveUrl+"/"+fileName);
                    }
                }
            }
        }
        return result;
        
    }
    
    public static UploadResult uploadLocation(HttpServletRequest request, String fileType, String location, Integer maxSize){
    	// 文件保存目录url
    	String dir = new SimpleDateFormat("yyyyMMdd").format(new Date());
    	
    	String saveUrl  = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+ request.getContextPath()+"/common/"+dir;  
    	//文件保存物理路径/common/
    	String savePath = location + File.separator + dir;
    	//创建文件保存文件夹
    	createFileDir(savePath);
    	
    	UploadResult result = new UploadResult();
    	
        //解析器解析request的上下文
        CommonsMultipartResolver multipartResolver = new CommonsMultipartResolver(request.getSession().getServletContext());
        //先判断request中是否包涵multipart类型的数据，
        if(multipartResolver.isMultipart(request)){
            //再将request中的数据转化成multipart类型的数据
            MultipartHttpServletRequest multiRequest = (MultipartHttpServletRequest)request;
            Iterator<String> iter = multiRequest.getFileNames();
            while(iter.hasNext()){
                MultipartFile file = multiRequest.getFile(iter.next());
                if(file != null){
                    String fileName = file.getOriginalFilename();
                    if(!fileName.trim().equals("")){
                        try(InputStream in = file.getInputStream();){
                        	if(maxSize!=null && file.getSize()>maxSize*1024){
                        		throw new MaxUploadSizeExceededException(maxSize*1024);
                        	}
                        	fileName = recreateFileName(getFileExt(fileName, fileType));
                        	FileUtil.writeFromStream(in,new File(savePath,fileName)); 
                        } catch (IOException e) {
                            result.setMessage("文件上传失败");
                            result.setSuccess(false);
                            result.getFileURLs().clear();
                            break;
                        } catch (MaxUploadSizeExceededException e){
                        	result.setMessage("上传文件大小超过限制");
                        	result.setSuccess(false);
                        	result.getFileURLs().clear();
                        	break;
                        } catch (Exception e){
                        	result.setMessage("上传文件扩展名是不允许的扩展名。\n只允许" + EXT_MAP.get(fileType) + "格式");
                        	result.setSuccess(false);
                        	result.getFileURLs().clear();
                        	break;
                        }
                        result.getFileURLs().add(saveUrl+"/"+fileName);
                        Map<String,Object> map = Maps.newHashMap();
                        map.put(saveUrl+"/"+fileName,savePath + File.separator + fileName);
                        result.getUrlAndSize().add(map);
                    }
                }
            }
        }
        return result;
        
    }
    /**
     * 
     *@Description: 上传flash（swf,flv）
     *@Author: afast
     *@Since: 2016-4-22上午09:19:59
     *@throws MaxUploadSizeExceededException
     *@throws IOException
     */
    public static UploadResult uploadFlash(HttpServletRequest request, String saveDir, Integer maxSize){
    
        return upload(request,"flash",saveDir,maxSize);
    }
    
    /**
     * 
     *@Description: 上传图片（gif,jpg,jpeg,png,bmp）
     *@Author: afast
     *@Since: 2016-4-22上午09:20:10
     *@throws MaxUploadSizeExceededException
     *@throws IOException
     */
    public static UploadResult uploadImage(HttpServletRequest request, String saveDir, Integer maxSize){
        
        return upload(request,"image",saveDir,maxSize);
    }
    


    /**
     * 
     *@Description: 上传媒体文件（swf,flv,mp3,wav,wma,wmv,mid,avi,mpg,asf,rm,rmvb）
     *@Author: afast
     *@Since: 2016-4-22上午09:20:20
     *@throws MaxUploadSizeExceededException
     *@throws IOException
     */
    public static UploadResult uploadMedia(HttpServletRequest request, String saveDir, Integer maxSize){
        
        return upload(request,"media",saveDir,maxSize);
    }
    
    
    /**
     * 
     *@Description: 上传文件（doc,docx,xls,xlsx,ppt,htm,html,txt,zip,rar,gz,bz2）
     *@Author: afast
     *@Since: 2016-4-22上午09:20:33
     *@throws MaxUploadSizeExceededException
     *@throws IOException
     */
    public static UploadResult uploadFile(HttpServletRequest request, String saveDir, Integer maxSize){
        
        return upload(request,"file",saveDir,maxSize);
    }
    /**
     * @Author: ShiQiang
     * @Since: 2019年4月12日14:34:57
     * @param url 请求路径
     */
    public static boolean deletePic(String url) { 
		return OSSBjOtherClientUtil.getInstance().deletePic(url);
	}
    /**
     * 
     *@Description: 重新生成一个文件名称
     *@Author: afast
     *@Since: 2016-4-22上午09:17:01
     *@return
     */
    private static String recreateFileName(String ext){
        
        SimpleDateFormat df = new SimpleDateFormat("yyyyMMddHHmmss");
        
        return df.format(new Date()) + "_" + new Random().nextInt(10000000) + "." + ext;
    }
    
    /**
     * 
     *@Description: 获取文件扩展
     *@Author: afast
     *@Since: 2016-4-22上午09:17:25
     *@param fileName
     *@return
     */
    private static String getFileExt(String fileName,String fileType)
        throws Exception{
       
        String ext = fileName.substring(fileName.lastIndexOf(".") + 1).toLowerCase();
        if(!Arrays.<String>asList(EXT_MAP.get(fileType).split(",")).contains(ext)){
            throw new Exception("上传文件扩展名是不允许的扩展名。\n只允许" + EXT_MAP.get(fileType) + "格式");
        }
        
        return ext;
    }
    
    
    /**
     * 
     *@Description: 生成文件保存URL
     *@Author: afast
     *@Since: 2016-4-22上午09:17:54
     *@param basePath
     *@return
     */
    public static String createSaveURL(String basePath){
    	basePath = basePath.startsWith("/") ? basePath : "/"+basePath;
    	basePath = basePath.endsWith("/") ? basePath : basePath + "/";
        return ROOt_BASE_PATH + basePath +  new SimpleDateFormat("yyyyMMdd").format(new Date());
    }
    public static String createSaveURLLocation(String basePath){
    	basePath = basePath.startsWith("/") ? basePath : "/"+basePath;
    	basePath = basePath.endsWith("/") ? basePath : basePath + "/";
        return basePath +  new SimpleDateFormat("yyyyMMdd").format(new Date());
    }
    /**
     * 
     *@Description: 生成文件保存URL
     *@Author: afast
     *@Since: 2016-4-22上午09:17:54
     *@param basePath
     *@return
     */
    public static String createSaveURLAli(String basePath){
    	basePath = basePath.startsWith("/") ? basePath : "/"+basePath;
    	basePath = basePath.endsWith("/") ? basePath : basePath + "/";
        return ROOT_BASE_PATH_ALI + basePath +  new SimpleDateFormat("yyyyMMdd").format(new Date());
    }

    /**
     * 上传 oss
     * @param request
     * @return
     * @throws IOException
     */
    public static UploadResult uploadOssPic(HttpServletRequest request) throws IOException {
        OSSBjOtherClientUtil ossClientUtil = OSSBjOtherClientUtil.getInstance();
        UploadResult uploadResult = ossClientUtil.uploadImg2OssMorePic(request,"upload/image/"+DateUtil.today(),false,"");
        return uploadResult;
    }
}
